"""
API routes for stock price prediction functionality.
"""

import logging
from datetime import datetime
from fastapi import APIRouter, HTTPException, Depends
from typing import Dict, Any, Optional

from ..models.prediction_models import PredictionRequest, PredictionResponse, PredictionError
from ..services.prediction_service import PredictionService

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/prediction", tags=["prediction"])

# 全局预测服务实例（单例模式，避免重复加载模型）
_prediction_service: Optional[PredictionService] = None

def get_prediction_service() -> PredictionService:
    """依赖注入：提供预测服务实例（单例模式）"""
    global _prediction_service
    if _prediction_service is None:
        _prediction_service = PredictionService()
    return _prediction_service


@router.post("/predict", response_model=PredictionResponse)
async def predict_stock_price(
    request: PredictionRequest,
    service: PredictionService = Depends(get_prediction_service)
) -> PredictionResponse:
    """
    使用 Kronos 时间序列模型预测股票价格
    
    Args:
        request: 包含股票代码和预测参数的请求
        service: 预测服务实例
    
    Returns:
        PredictionResponse: 包含置信区间的预测结果
    
    Raises:
        HTTPException: 预测失败时抛出
    """
    try:
        logger.info(f"收到股票 {request.stock_code} 的预测请求，预测天数: {request.prediction_days}")
        
        # 验证股票代码格式
        if not request.stock_code or len(request.stock_code.strip()) == 0:
            raise HTTPException(status_code=400, detail="股票代码不能为空")
        
        # 执行预测
        result = await service.predict_stock_price(request)
        
        logger.info(f"股票 {request.stock_code} 预测完成，生成 {len(result.predictions)} 个预测点")
        return result
        
    except PredictionError as e:
        logger.error(f"预测错误: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except ValueError as e:
        logger.error(f"参数错误: {str(e)}")
        raise HTTPException(status_code=400, detail=f"参数错误: {str(e)}")
    except Exception as e:
        logger.error(f"预测端点发生意外错误: {str(e)}")
        raise HTTPException(status_code=500, detail="预测服务内部错误")


